home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
001
/
pibt3sp4.arc
/
SENDMDM7.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1985-10-04
|
19KB
|
457 lines
(*----------------------------------------------------------------------*)
(* Send_Modem7_File --- Upload file with Modem7/Telink *)
(*----------------------------------------------------------------------*)
PROCEDURE Send_Modem7_File( Use_CRC: BOOLEAN );
(*----------------------------------------------------------------------*)
(* *)
(* Procedure: Send_Modem7_File *)
(* *)
(* Purpose: Uploads file using Modem7/Telink batch *)
(* *)
(* Calling Sequence: *)
(* *)
(* Send_Modem7_File( Use_CRC: BOOLEAN); *)
(* *)
(* Use_CRC --- TRUE to use CRC checking; *)
(* FALSE to use Checksum checking. *)
(* *)
(* Calls: KeyPressed *)
(* Async_Send *)
(* Async_Receive_With_TimeOut *)
(* Get_Modem7_File_Name *)
(* Check_KeyBoard *)
(* RvsVideoOn *)
(* RvsVideoOff *)
(* Wait_For_Nak *)
(* Send_File_Name *)
(* Perform_Upload *)
(* *)
(* Remarks: *)
(* *)
(* This routine performs wildcard directory searches and *)
(* implements the Modem7 and Telink batch file transfer *)
(* protocols. *)
(* *)
(*----------------------------------------------------------------------*)
VAR
File_Pattern : AnyStr;
SFileName : PACKED ARRAY[1..11] OF CHAR;
Int_Ch : INTEGER;
Ch : CHAR;
CheckSum : INTEGER;
EndFName : BOOLEAN;
I : INTEGER;
J : INTEGER;
Local_Save : Saved_Screen_Ptr;
Tname : STRING[10];
File_Entry : Directory_Record;
Ack_OK : BOOLEAN;
OK_File : BOOLEAN;
Batch_Title : AnyStr;
(*----------------------------------------------------------------------*)
(* Check_KeyBoard --- Check for keyboard input *)
(*----------------------------------------------------------------------*)
PROCEDURE Check_KeyBoard;
BEGIN (* Check_KeyBoard *)
(* If Alt_R found, stop transfer *)
IF KeyPressed THEN
BEGIN
READ( Kbd, Ch );
IF ( Ch = CHR( ESC ) ) AND KeyPressed THEN
BEGIN
READ( Kbd, Ch );
IF ORD( Ch ) = Alt_S THEN
BEGIN
Stop_Send := TRUE;
WRITELN(' Alt_S accepted, transfer cancelled.');
END;
END;
END;
END (* Check_KeyBoard *);
(*----------------------------------------------------------------------*)
(* Make_Telink_Header --- Send special TELINK header block *)
(*----------------------------------------------------------------------*)
PROCEDURE Make_Telink_Header;
(*----------------------------------------------------------------------*)
(* *)
(* Procedure: Make_Telink_Header *)
(* *)
(* Purpose: Makes special TELINK header block *)
(* *)
(* Calling sequence: *)
(* *)
(* Make_Telink_Header; *)
(* *)
(* Calls: None *)
(* *)
(* Remarks: *)
(* *)
(* The Telink header block is ALWAYS sent in Checksum mode, *)
(* regardless of whether or not the files are to be sent in *)
(* CRC or checksum mode. *)
(* *)
(* Format of Telink block: *)
(* *)
(* Bytes Contents *)
(* ----- --------------------------------------- *)
(* *)
(* 1 SYN *)
(* 2 0 *)
(* 3 255 *)
(* 4-7 File size in MS DOS directory form *)
(* 8-9 Creation date in MS DOS form *)
(* 10-11 Creation time in MS DOS form *)
(* 12-27 Name of file in 'name.ext' form *)
(* 28 Version number (always zero here) *)
(* 29-44 PIBTERM -- sending program's name *)
(* 45-131 All zeroes *)
(* 132 Checksum of block *)
(* *)
(* The first three bytes are added later by the Xmodem send *)
(* routine. The rest are constructed here. *)
(* *)
(*----------------------------------------------------------------------*)
VAR
I : INTEGER;
J : INTEGER;
L : INTEGER;
CheckSum : INTEGER;
ACK_Ok : BOOLEAN;
Int_Ch : INTEGER;
BEGIN (* Make_Telink_Header *)
(* Zero out block *)
FOR I := 1 TO 130 DO
Sector_Data[I] := 0;
(* File size in 32-bit MS DOS form *)
Sector_Data[1] := LO( File_Entry.File_Size[1] );
Sector_Data[2] := HI( File_Entry.File_Size[1] );
Sector_Data[3] := LO( File_Entry.File_Size[2] );
Sector_Data[4] := HI( File_Entry.File_Size[2] );
(* Creation date in MS DOS form *)
Sector_Data[5] := LO( File_Entry.File_Time );
Sector_Data[6] := HI( File_Entry.File_Time );
(* Creation time in MS DOS form *)
Sector_Data[7] := LO( File_Entry.File_Date );
Sector_Data[8] := HI( File_Entry.File_Date );
(* File name *)
L := LENGTH( FileName );
FOR I := 1 TO L DO
Sector_Data[I+8] := ORD( FileName[I] );
FOR I := ( L + 1 ) TO 16 DO
Sector_Data[I+8] := ORD(' ');
(* Sending program's name *)
FOR I := 1 TO 16 DO
Sector_Data[I+25] := ORD( COPY( 'PIBTERM ', I, 1 ) );
(* Compute checksum *)
CheckSum := 0;
FOR I := 1 TO 128 DO
CheckSum := ( CheckSum + Sector_Data[I] ) AND 255;
Sector_Data[129] := CheckSum;
END (* Make_Telink_Header *);
(*----------------------------------------------------------------------*)
(* Get_Modem7_File_Name --- Construct file name to MODEM7 form *)
(*----------------------------------------------------------------------*)
PROCEDURE Get_Modem7_File_Name( VAR OK_File : BOOLEAN );
(*----------------------------------------------------------------------*)
(* *)
(* Remarks: *)
(* *)
(* The filename for Modem7 is 11 characters long. The filename *)
(* is left-justified and blank-filled in the first 8 characters. *)
(* The extension appears left-justified and blank-filled in *)
(* positions 9 through 11. *)
(* *)
(* Examples: *)
(* 12345678901 *)
(* 'root.dat' becomes: root dat *)
(* 'root' becomes: root *)
(* *)
(* Note that the checksum INCLUDES the terminating Ctrl-z (SUB) *)
(* character of the file name. *)
(* *)
(* In host mode, a check is made to ensure that the file to be *)
(* sent is on the transfer list. If not, it is not sent. *)
(* *)
(*----------------------------------------------------------------------*)
BEGIN (* Get_Modem7_File_Name *)
I := 1;
J := 0;
SFileName := ' ';
FileName := '';
WHILE( File_Entry.File_Name[I] <> CHR( 0 ) ) AND ( I <= 12 ) DO
BEGIN
Ch := File_Entry.File_Name[I];
IF Ch = '.' THEN
J := 8
ELSE
BEGIN
J := J + 1;
SFileName[J] := Ch;
END;
FileName := FileName + Ch;
I := I + 1;
END;
(* Get checksum *)
CheckSum := 0;
FOR I := 1 TO 11 DO
CheckSum := ( CheckSum + ORD( SFileName[I] ) ) AND 255;
CheckSum := ( CheckSum + SUB ) AND 255;
OK_File := ( File_Entry.File_Attr AND
( Dir_Attr_Volume_Label + Dir_Attr_Subdirectory ) = 0 );
(* If host mode, make sure file *)
(* is on xferlist! *)
IF Host_Mode THEN
OK_File := Scan_Xfer_List( FileName );
END (* Get_Modem7_File_Name *);
(*----------------------------------------------------------------------*)
(* Wait_For_Nak --- Wait for NAK at start of file name *)
(*----------------------------------------------------------------------*)
PROCEDURE Wait_For_Nak;
BEGIN (* Wait_For_Nak *)
I := 0;
(* Wait up to minute for NAK *)
REPEAT
Async_Receive_With_Timeout( One_Second , Int_Ch );
Check_KeyBoard;
I := I + 1;
UNTIL ( Int_Ch = NAK ) OR
( I >= 60 ) OR
Stop_Send;
IF ( Int_Ch <> NAK ) THEN
BEGIN
Stop_Send := TRUE;
WRITELN(' NAK for start of file name not received;');
WRITELN(' Received Ascii ',Int_Ch,' instead.');
END
ELSE (* If NAK found, ACK it *)
BEGIN
WRITELN(' NAK for start of file name received.');
Async_Send( CHR( ACK ) );
END;
(* Wait for com line to clear *)
Async_Purge_Buffer;
END (* Wait_For_Nak *);
(*----------------------------------------------------------------------*)
(* Send_File_Name --- Send file name characters *)
(*----------------------------------------------------------------------*)
PROCEDURE Send_File_Name;
(*----------------------------------------------------------------------*)
(* *)
(* Remarks: *)
(* *)
(* The file name characters are sent one at a time. After *)
(* each is sent, we wait for an ACK. To end the file name *)
(* we send an SUB (ctrl-z) character. *)
(* *)
(*----------------------------------------------------------------------*)
BEGIN (* Send_File_Name *)
I := 0;
WHILE( NOT Stop_Send ) AND ( I < 11 ) DO
BEGIN
I := I + 1;
Async_Send( SFileName[I] );
Async_Receive_With_TimeOut( Ten_Seconds , Int_Ch );
Ack_OK := ( Int_Ch = ACK );
Check_KeyBoard;
Stop_Send := Stop_Send OR ( NOT Ack_OK );
END;
(* Send End of file name character *)
(* and await receiver to send *)
(* checksum. *)
IF NOT Stop_Send THEN
BEGIN
Async_Send( CHR( SUB ) );
Async_Receive_With_TimeOut( Ten_Seconds , Int_Ch );
IF ( Int_Ch <> CheckSum ) THEN
BEGIN
Stop_Send := TRUE;
WRITELN(' Received checksum for filename not correct;');
WRITELN(' Correct checksum = ',CheckSum,', received ',Int_Ch);
END
ELSE
Async_Send( CHR( ACK ) );
END;
END (* Send_File_Name *);
(*----------------------------------------------------------------------*)
(* Perform_Upload --- Do the upload *)
(*----------------------------------------------------------------------*)
PROCEDURE Perform_Upload;
BEGIN (* Perform_Upload *)
Writelne(' Uploading: ' + FileName , TRUE );
IF Transfer_Protocol = Telink THEN
Make_Telink_Header;
IF ( NOT Stop_Send ) THEN
Send_Xmodem_File( Use_CRC );
TextColor( Menu_Text_Color );
END (* Perform_Upload *);
(*----------------------------------------------------------------------*)
BEGIN (* Send_Modem7_File *)
(* Open display window for transfers *)
Save_Screen( Local_Save );
CASE Transfer_Protocol OF
Telink : Tname := 'Telink';
Modem7_Chk : Tname := 'Modem7 (Checksum)';
Modem7_CRC : Tname := 'Modem7 (CRC)';
END (* CASE *);
(* Always CRC for Telink *)
Use_CRC := Use_CRC OR ( Transfer_Protocol = Telink );
Batch_Title := 'Batch file upload using ' + Tname;
Draw_Menu_Frame( 2, 2, 79, 24, Menu_Frame_Color,
Menu_Text_Color, Batch_Title );
Writelne( Batch_Title , FALSE );
Window( 3, 3, 78, 23 );
(* Get file name pattern to send *)
File_Pattern := FileName;
(* See if we can find anything to *)
(* be sent. *)
Stop_Send := ( Dir_Find_First_File( File_Pattern, File_Entry ) <> 0 );
IF Stop_Send THEN
WRITELN(' No files found to send.');
(* Loop over file names *)
WHILE( NOT Stop_Send ) DO
BEGIN
(* Get file name *)
Get_Modem7_File_Name( OK_File );
(* If file can be sent, do it *)
IF OK_File THEN
BEGIN
(* Wait for NAK indicating host *)
(* is ready for the file name. *)
IF NOT Stop_Send THEN
Wait_For_Nak;
(* Send file name characters *)
IF NOT Stop_Send THEN
Send_File_Name;
(* Send the file itself *)
IF NOT Stop_Send THEN
Perform_Upload;
END;
(* See if more files to transfer *)
Stop_Send := Stop_Send OR ( Dir_Find_Next_File( File_Entry ) <> 0 );
END (* While *);
(* Purge reception *)
REPEAT
Async_Receive_With_Timeout( One_Second , Int_Ch );
UNTIL ( Int_Ch = TimeOut );
(* Send EOT to indicate no more files *)
Async_Send( CHR( EOT ) );
(* Wait for ACK *)
Async_Receive_With_TimeOut( Ten_Seconds , Int_Ch );
IF ( Int_Ch = ACK ) THEN
BEGIN
Writelne(' ', TRUE);
Writelne(' Host system ACKnowledged EOT.', TRUE);
END;
(* Indicate end of transfer *)
Writelne(' ', TRUE);
RvsVideoOn ( Menu_Text_Color, BackGround_Color );
Writelne(' Batch transfer complete.' , TRUE);
RvsVideoOff( Menu_Text_Color, BackGround_COlor );
DELAY( Two_Second_Delay );
(* Remove batch transfer window *)
Restore_Screen( Local_Save );
Reset_Global_Colors;
END (* Send_Modem7_File *);